package com.wtwd.device.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.wtwd.device.model.vo.PageDataVO;
import com.wtwd.device.model.vo.ResultVO;
import com.wtwd.device.constant.RespCode;
import com.wtwd.device.model.entity.*;
import com.wtwd.device.model.vo.ExcleExportVo;
import com.wtwd.device.model.vo.RespEntity;
import com.wtwd.device.model.vo.WatchVo;
import com.wtwd.device.service.CustomerService;
import com.wtwd.device.service.DeviceInfoService;
import com.wtwd.device.utils.GetCurrentSysUserInfoUtils;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mjy
 * @date 2021/08/06
 * @description
 */
@Api(tags = "设备管理")
@RestController
@RequestMapping("/device")
public class DeviceInfoController {

    private static final Logger logger = LoggerFactory.getLogger(DeviceInfoController.class);

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private GetCurrentSysUserInfoUtils getCurrentSysUserInfoUtils;

    @Autowired
    private CustomerService customerService;


    /**
     * 获取设备管理列表
     *
     * @param currentPage
     * @param pageSize
     * @param macAddress
     * @param activation
     * @param customerName
     * @return
     */
    @ApiOperation(value = "分页获取设备管理列表", notes = "0:未激活,1:激活")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页", required = true, dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "pageSize", value = "页面大小", required = true, dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "macAddress", value = "mac地址", dataType = "String")
            , @ApiImplicitParam(name = "activation", value = "是否激活", dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "customerName", value = "客户名称", dataType = "String")

    })
    @GetMapping("/getWatchList01")
    public ResultVO<PageDataVO<WatchVo>> getWatchList01(@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage
            , @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
            , @RequestParam(value = "macAddress", required = false) String macAddress
            , @RequestParam(value = "activation", required = false) Integer activation
            , @RequestParam(value = "customerName", required = false) String customerName) {
        logger.info("getWatchList param  " + currentPage, pageSize, macAddress, activation, customerName);
        SysUser sysUser = getCurrentSysUserInfoUtils.getCurrentSysUserInfo();
        if (sysUser == null) {
            return ResultVO.error(RespCode.TOKEN_UNAUTHORIZED);
        }
        if (StringUtils.isBlank(macAddress)) {
            macAddress = null;
        }
        if (StringUtils.isBlank(customerName)) {
            customerName = null;
        }
        Page<Object> page = new Page<>(currentPage, pageSize);
        HashMap<String, Object> searchMap = new HashMap<>();
        searchMap.put("macAddress", macAddress);
        searchMap.put("activation", activation);
        searchMap.put("customerName", customerName);
        searchMap.put("customerId", sysUser.getCustomerId());
        IPage<WatchVo> watches = deviceInfoService.getWatchListByConditions(searchMap, page);
        PageDataVO<WatchVo> pageDataVO = new PageDataVO<>();
        pageDataVO.setTotal(watches.getTotal());
        pageDataVO.setRows(watches.getRecords());
        return ResultVO.success(RespCode.SUCCESS, pageDataVO);
    }

    @ApiOperation(value = "分页获取设备管理列表", notes = "0:未激活,1:激活")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页", required = true, dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "pageSize", value = "页面大小", required = true, dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "macAddress", value = "mac地址", dataType = "String")
            , @ApiImplicitParam(name = "activation", value = "是否激活", dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "customerName", value = "客户名称", dataType = "String")

    })
    @GetMapping("/getWatchList")
    public ResultVO<PageDataVO<WatchVo>> getWatchList(@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage
            , @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
            , @RequestParam(value = "macAddress", required = false) String macAddress
            , @RequestParam(value = "activation", required = false) Integer activation
            , @RequestParam(value = "customerName", required = false) String customerName) {
        logger.info("getWatchList01 param  " + currentPage, pageSize, macAddress, activation, customerName);
        SysUser sysUser = getCurrentSysUserInfoUtils.getCurrentSysUserInfo();
        if (sysUser == null) {
            return ResultVO.error(RespCode.TOKEN_UNAUTHORIZED);
        }
        List<Customer> customers = null;
        if (StringUtils.isNotBlank(customerName)) {//查询匹配客户
            customers = customerService.getCustomerByLikeName(customerName);
        }else {//查询全部
            customers=customerService.getAllCustomer();
        }
        if (customers==null||customers.size()==0){
            IPage watchVoPage = new Page<>();
            watchVoPage.setRecords(new ArrayList());
            watchVoPage.setTotal(0);
            return ResultVO.success(RespCode.SUCCESS, watchVoPage);
        }
        Page<Device> page = new Page<>(currentPage, pageSize);
        List<Long> customerIds = customers.stream().map(Customer::getId).collect(Collectors.toList());
        IPage devices = deviceInfoService.getWatchListByConditionsPage(macAddress, activation,sysUser.getCustomerId(),customerIds,page);
        //page出来的后的数据是分页之后的数据，数据量并不会过大
        List<WatchVo> watchVos = new ArrayList<>();
        List records = devices.getRecords();
        for (Object e : records) {
            Device device = (Device) e;
            WatchVo watchVo = new WatchVo();
            BeanUtils.copyProperties(device,watchVo);
            if (watchVo.getPreviousVersion()==null){//这里主要是因为前段不好处理控制空值
                watchVo.setPreviousVersion("");
            }
            Customer customer1 =null;
            if (customers!=null&&customers.size()>0){
                 customer1 = customers.stream().filter(customer -> customer.getId().equals(device.getCustomerId())).findFirst().get();
            }
            if (customer1!=null){
                watchVo.setCustomerName(customer1.getName());
            }else {
                watchVo.setCustomerName("");
            }
            watchVos.add(watchVo);
        }
        devices.setRecords(watchVos);
        return ResultVO.success(RespCode.SUCCESS, devices);
    }


    /**
     * 导出设备
     *
     * @param macAddress
     * @param activation
     * @param customerName
     * @return
     */
    @ApiOperation(value = "导出设备", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "macAddress", value = "mac地址", required = false, dataTypeClass = String.class)
            , @ApiImplicitParam(name = "activation", value = "是否激活 0：未激活,1：激活", required = false, dataTypeClass = Integer.class)
            , @ApiImplicitParam(name = "customerName", value = "客户名称", dataType = "String", required = false)

    })
    @ApiResponses({@ApiResponse(code = 6001, message = "请输入正确且完整的客户名称")})
    @GetMapping("/exportDeviceInfo")
    public RespEntity<ExcleExportVo> exportDeviceInfo(@RequestParam(value = "macAddress") String macAddress
            , @RequestParam(value = "activation") Integer activation
            , @RequestParam(value = "customerName") String customerName, HttpServletResponse response) {
        logger.info("exportDeviceInfo param  " + macAddress, activation, macAddress, customerName);
        SysUser sysUser = getCurrentSysUserInfoUtils.getCurrentSysUserInfo();
        if (sysUser == null) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        if (StringUtils.isBlank(macAddress)) {
            macAddress = null;
        }
        if (StringUtils.isBlank(customerName)) {
            customerName = null;
        }
        //校验规则
        RespEntity respEntity = checkDeviceExport(sysUser.getCustomerId(), customerName);
        if (respEntity.getCode() != RespCode.SUCCESS.getCode()) {
            return respEntity;
        }
        return deviceInfoService.exportDeviceInfo(macAddress, activation, customerName, sysUser.getCustomerId(), response);
    }


    /**
     * 批量删除设备
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("批量删除设备")
    @DynamicParameters(name = "batchDeleteDevice", properties = {
            @DynamicParameter(name = "deviceIdList", value = "设备id集合", dataTypeClass = Arrays.class, required = true)
    })
    @PostMapping("/batchDeleteDevice")
    public RespEntity batchDeleteDevice(@RequestBody JSONObject jsonObject) {
        logger.info("getWatchList param  " + jsonObject);
        List<Integer> deviceIdList = jsonObject.getJSONArray("deviceIdList").toJavaList(Integer.class);
        Integer rest = deviceInfoService.bathDelDeviceByDeviceIdList(deviceIdList);
        return new RespEntity(rest > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }


    /**
     * 单个删除设备
     *
     * @param deviceId
     * @return
     */
    @ApiOperation("单个删除设备")
    @DynamicParameters(name = "deleteDevice", properties = {
            @DynamicParameter(name = "deviceIdList", value = "设备id集合", dataTypeClass = Arrays.class, required = true)
    })
    @DeleteMapping("/deleteDevice/{deviceId}")
    public RespEntity deleteDevice(@PathVariable Integer deviceId) {
        logger.info("deleteDevice param  " + deviceId);
        Integer rest = deviceInfoService.deleteDeviceByDeviceId(deviceId);
        return new RespEntity(rest > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 导入设备
     *
     * @param file
     * @param response
     * @param request
     * @return
     */
    @ApiOperation("导入设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件", required = true, dataTypeClass = MultipartFile.class)
    })
    @PostMapping("/importDeviceInfo")
    public RespEntity importDeviceInfo(@RequestParam MultipartFile file, HttpServletResponse response, HttpServletRequest request) {
        logger.info("importDeviceInfo");
        SysUser sysUser = getCurrentSysUserInfoUtils.getCurrentSysUserInfo();
        if (sysUser == null) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        return deviceInfoService.importDeviceInfo(file, sysUser, response);
    }

    /**
     * 根据范围导入设备
     *
     * @param deviceInfoByRangeDto
     * @return
     * @date 2023.9.19
     */
    @ApiOperation("根据范围导入设备")
    @PostMapping("/batchImportDeviceInfoByRange")
    public RespEntity batchImportDeviceInfoByRange(@RequestBody DeviceInfoByRangeDto deviceInfoByRangeDto) {
        logger.info("batchImportDeviceInfoByRange:" + deviceInfoByRangeDto);
        return deviceInfoService.batchImportDeviceInfoByRange(deviceInfoByRangeDto);
    }

    /**
     * 通过macAddress,激活设备并上传手表id,和当前手表版本
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("激活设备")
    @DynamicParameters(name = "activationDevice", properties = {
            @DynamicParameter(name = "macAddress", value = "mac地址", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "watchId", value = "手表id", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "currentFirmware", value = "当前手表版本", dataTypeClass = String.class, required = true)
    })
    @PutMapping("/activationDevice")
    public RespEntity activationDevice(@RequestBody JSONObject jsonObject) {
        logger.info("activationDevice" + jsonObject);
        String macAddress = jsonObject.getString("macAddress");
        String watchId = jsonObject.getString("watchId");
        String currentFirmware = jsonObject.getString("currentFirmware");
        return deviceInfoService.activeDevice(macAddress, watchId, currentFirmware, 1);
    }

    /**
     * 检验设备导出客户名称
     *
     * @param customerName
     * @return
     */
    private RespEntity checkDeviceExport(Long customerId, String customerName) {
        if (customerId == null || customerId == 0) {//超管
            if (StringUtils.isBlank(customerName)) {
                return new RespEntity(RespCode.CUSTOMER_NOT_EXIST);
            }
            Customer customer = customerService.getCustomerByName(customerName);
            if (customer == null) {
                return new RespEntity(RespCode.CUSTOMER_NOT_EXIST);
            }
        }
        //不是超管针对自己的设备导出，在sql中处理
        return new RespEntity(RespCode.SUCCESS);
    }


    /**
     * 通过macAddress,激活设备并上传手表id,和当前手表版本
     *
     * @param data
     * @return
     */
    @ApiOperation("解除绑定")
    @PostMapping("/unBindDevice")
    public RespEntity unBindDevice(@RequestBody UnBindDevicedDto data) {
        deviceInfoService.unBindDeviceByMac(data.getMac());
        return new RespEntity(RespCode.SUCCESS);
    }

}
